﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ProcessBase.Models;
using SubstrateHelper.Data;

namespace SubstrateHelper.Helpers
{
    public class ProcessStatisticsHelper
    {
        public static ProcessStatistics MakeStatistics(string guid)
        {
            ProcessStatistics statistics;
            using (var scope = Global.Host.Services.CreateScope())
            {
                var services = scope.ServiceProvider;
                try
                {
                    var Db = services.GetRequiredService<SubstrateHelperDbContext>();

                    Record record;
                    Parameter parameter;
                    statistics = new ProcessStatistics();

                    //guid
                    statistics.Guid = guid;

                    //[DisplayName("工序名")]
                    //public string ProcessName { get; set; }
                    //[DisplayName("来料标识")]
                    //public string LotNoInput { get; set; }
                    record = Db.Records.Where(x => x.Guid == guid && x.ParameterName == "来料标识").FirstOrDefault();
                    statistics.ProcessName = record.ProcessName;
                    statistics.LotNoInput = record.StringValue;


                    //[DisplayName("主批号")]
                    //public string LotNoOutput { get; set; }
                    record = Db.Records.Where(x => x.Guid == guid && x.ParameterName == "主批号").FirstOrDefault();
                    statistics.MainLotNo = record.StringValue;


                    //[DisplayName("产出标识")]
                    //public string LotNoOutput { get; set; }
                    record = Db.Records.Where(x => x.Guid == guid && x.ParameterName == "产出标识").FirstOrDefault();
                    statistics.LotNoOutput = record.StringValue;

                    //[DisplayName("来料数量")]
                    //public double QuantityInput { get; set; }
                    record = Db.Records.Where(x => x.Guid == guid && x.ParameterName == "来料数量").FirstOrDefault();
                    statistics.QuantityInput = record.NumberValue;

                    //[DisplayName("来料单位")]
                    //public string QuantityInputUnit { get; set; }
                    parameter = Db.Parameters.Where(x => x.ProcessName == statistics.ProcessName && x.ParameterName == "来料数量").FirstOrDefault();
                    statistics.QuantityInputUnit = parameter.ParameterUnit;


                    //[DisplayName("产出数量")]
                    //public double QuantityOutput { get; set; }
                    record = Db.Records.Where(x => x.Guid == guid && x.ParameterName == "产出数量").FirstOrDefault();
                    statistics.QuantityOutput = record.NumberValue;

                    //[DisplayName("产出单位")]
                    //public string QuantityOutputUnit { get; set; }
                    parameter = Db.Parameters.Where(x => x.ProcessName == statistics.ProcessName && x.ParameterName == "产出数量").FirstOrDefault();
                    statistics.QuantityOutputUnit = parameter.ParameterUnit;

                    //[DisplayName("进站日期")]
                    //public DateTime DateIn { get; set; }
                    record = Db.Records.Where(x => x.Guid == guid && x.ParameterName == "进站日期").FirstOrDefault();
                    statistics.DateIn = record.DateTimeValue;

                    //[DisplayName("出站日期")]
                    //public DateTime? DateOut { get; set; }
                    record = Db.Records.Where(x => x.Guid == guid && x.ParameterName == "出站日期").FirstOrDefault();
                    statistics.DateOut = record.DateTimeValue;

                    _CompleteStatistics(statistics,Db);
                }
                catch (Exception ex)
                {
                    statistics = null;
                    var logger = services.GetRequiredService<ILogger<Program>>();
                    logger.LogError(ex, "MakeStatistics");
                }
            }

            return statistics;
        }

        static void _CompleteStatistics(ProcessStatistics statistics, SubstrateHelperDbContext Db)
        {
            //工序状态
            if (statistics.DateIn != null)
            {
                var days = Db.ProcessDayLimits.Where(x => x.ProcessName == statistics.ProcessName).Select(x => x.DaysLimit).FirstOrDefault();
                if (statistics.DateOut == null)//未完成
                {
                    var span = (DateTime.Now.Date - statistics.DateIn.Value.Date).TotalDays;
                    if (span > days)//逾期
                    {
                        statistics.ProcessState = "未完成【逾期】";
                    }
                    else
                    {
                        statistics.ProcessState = "未完成";
                    }

                }
                else
                {
                    var span = (statistics.DateOut.Value.Date - statistics.DateIn.Value.Date).TotalDays;
                    if (span > days)//逾期
                    {
                        statistics.ProcessState = "已出站【逾期】";
                    }
                    else
                    {
                        statistics.ProcessState = "已出站";
                    }
                }

            }

            //质量状态

            var paras = Db.Parameters.Where(x => x.ProcessName == statistics.ProcessName && x.IsCheckPoint).ToList();
            int state = 0;
            foreach (var para in paras)
            {
                var _state = _GetStateInt(Db.Records.Where(x => x.Guid == statistics.Guid && x.ParameterName == para.ParameterName).Select(x => x.QualityState).FirstOrDefault());
                if (_state == 4)
                {
                    state = _state;
                    break;
                }
                else if (_state > state)
                {
                    state = _state;
                }
            }

            statistics.QualityState = _GetStateStr(state);

        }

        static int _GetStateInt(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return 1;//未处理
            }

            int re = 0;

            switch (str)
            {
                case "报废":
                    re = 4;
                    break;
                case "扣留":
                    re = 3;
                    break;
                case "让步流通":
                    re = 2;
                    break;
                default:
                    break;

            }
            return re;

        }

        static string _GetStateStr(int state)
        {
            string str;
            switch (state)
            {
                case 0:
                    str = "正常流通";
                    break;
                case 1:
                    str = "未处理";
                    break;
                case 2:
                    str = "让步流通";
                    break;
                case 3:
                    str = "扣留";
                    break;
                case 4:
                    str = "报废";
                    break;
                default:
                    str = "未知";
                    break;
            }

            return str;
        }


        public static string UpdateStatistics(IEnumerable<string> guids)
        {


            try
            {

                using (var scope = Global.Host.Services.CreateScope())
                {
                    var services = scope.ServiceProvider;
                    var Db = services.GetRequiredService<SubstrateHelperDbContext>();

                    if (guids != null)
                    {
                        foreach (var guid in guids)
                        {
                            var st = MakeStatistics(guid);
                            if (st != null)
                            {
                                var stInDb = Db.ProcessStatistics.Where(x => x.Guid == guid).FirstOrDefault();
                                if (stInDb == null)//数据库未有该记录
                                {
                                    Db.ProcessStatistics.Add(st);
                                }
                                else
                                {
                                    stInDb.CopyFrom(st);
                                }
                                
                            }
                        }
                        Db.SaveChanges();
                    }

                }

                
            }
            catch(Exception ex)
            {
                return ex.Message;
            }
            return null;
        }
    }
}
